package oris.components;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.border.AbstractBorder;

public class OrisBorder extends AbstractBorder{

    Insets borderSize = new Insets(5, 5, 5, 0);
    
    /**
     * Construtor padrão de borda.
     * Utiliza bordas de 3px.
     */
    public OrisBorder(){
        
    }

    /**
     * Constrói uma borda com sua largura inserida pelo usuário.
     * @param borderSize A largura da borda.
     */
    public OrisBorder(Insets borderSize){
        this.borderSize = borderSize;
    }
    
    /**
     * Retorna a largura atual da borda.
     * @return A largura da borda.
     */
    public Insets getBorderSize() {
        return borderSize;
    }

    /**
     * Modifica a largura da bora.
     * @param borderSize A nova largura.
     */
    public void setBorderSize(Insets borderSize) {
        this.borderSize = borderSize;
    }
    
    /**
     * Verifica se a posição dada pelo usuário está por cima da borda.
     * @param size A dimensão do objeto que contém a borda.
     * @param x A posição no eixo X.
     * @param y A posição no eyxo Y.
     * @return Verdadeiro se está em cima da borda.
     */
    public boolean isOnBorder(Dimension size, int x, int y){
        boolean isOnBorder = false;
        
        if(y >= size.height - borderSize.top){
            isOnBorder = true;
        }else if(y <= borderSize.bottom){
            isOnBorder = true;
        }else if(x >= size.width - borderSize.right){
            isOnBorder = true;
        }else if(x <= borderSize.left){
            isOnBorder = true;
        }
        
        return isOnBorder;
    }
    
    /**
     * Verifica em qual borda está o usuário.
     * @param size A dimensão do objeto que contém a borda.
     * @param x A posição no eixo X.
     * @param y A posição no eixo Y.
     * @return A direção em que se encontra o usuário.
     */
    public EnumDirecoes isInWhichEdge(Dimension size, int x, int y){
        EnumDirecoes edge = EnumDirecoes.NADA;
        
        //Nordeste
        if(x >= size.width-borderSize.right && y <= borderSize.top){
            edge = EnumDirecoes.NORDESTE;
        }
        //Sudeste
        else if(x >= size.width-borderSize.right && y >= size.height-borderSize.bottom){
            edge = EnumDirecoes.SUDESTE;
        }
        //Sudoeste
        else if(x <= borderSize.left && y >= size.height-borderSize.bottom){
            edge = EnumDirecoes.SUDOESTE;
        }
        //Noroeste
        else if(x <= borderSize.left && y <= borderSize.top){
            edge = EnumDirecoes.NOROESTE;
        }
        //Norte
        else if(y <= borderSize.top){
            edge = EnumDirecoes.NORTE;
        }
        //Leste
        else if(x >= size.width-borderSize.right){
            edge = EnumDirecoes.LESTE;
        }
        //Sul
        else if(y >= size.height-borderSize.bottom){
            edge = EnumDirecoes.SUL;
        }
        //Oeste
        else if(x <= borderSize.left){
            edge = EnumDirecoes.OESTE;
        }
        
        return edge;
    }
    
    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        
        //Borda superior
        if(topColor != null){
            g.setColor(topColor);
        }else{
            g.setColor(c.getBackground());
        }
        for(int i = 0; i < borderSize.top; i++){
            g.setColor(g.getColor().brighter());
            g.drawLine(0+i, i, width-i, i);
        }
        
        //Borda inferior
        if(bottomColor != null){
            g.setColor(bottomColor);
        }else{
            g.setColor(c.getBackground());
        }
        for(int i = borderSize.bottom-1; i >= 0; i--){
            g.setColor(g.getColor().darker());
            g.drawLine(i, height-i, width-i, height-i);
        }
        
        //Borda esquerda
        if(leftColor != null){
            g.setColor(leftColor);
        }else{
            g.setColor(c.getBackground());
        }
        for(int i = 0; i < borderSize.left; i++){
            g.setColor(g.getColor().brighter());
            g.drawLine(i, i, i, height-i);
        }
        
        //Borda direita
        if(rightColor != null){
            g.setColor(rightColor);
        }else{
            g.setColor(c.getBackground());
        }
        for(int i = 0; i < borderSize.right; i++){
            g.setColor(g.getColor().darker());
            g.drawLine(width-i, i, width-i, height-i);
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Colors">
    
    Color topColor = null;
    Color bottomColor = null;
    Color leftColor = null;
    Color rightColor = null;

    /**
     * Define a cor da borda superior.
     * Se o valor não for definido, ou o parâmetro da cor for nulo,
     * a cor da borda será desenhada utilizando-se a cor de fundo do componente.
     * @param color A cor da borda superior.
     */
    public void setTopColor(Color color){
        this.topColor = color;
    }

    /**
     * Define a cor da borda inferior.
     * Se o valor não for definido, ou o parâmetro da cor for nulo,
     * a cor da borda será desenhada utilizando-se a cor de fundo do componente.
     * @param color A cor da borda inferior.
     */
    public void setBottomColor(Color color){
        this.bottomColor = color;
    }

    /**
     * Define a cor da borda esquerda.
     * Se o valor não for definido, ou o parâmetro da cor for nulo,
     * a cor da borda será desenhada utilizando-se a cor de fundo do componente.
     * @param color A cor da borda esquerda.
     */
    public void setLeftColor(Color color){
        this.leftColor = color;
    }

    /**
     * Define a cor da borda direita.
     * Se o valor não for definido, ou o parâmetro da cor for nulo,
     * a cor da borda será desenhada utilizando-se a cor de fundo do componente.
     * @param color A cor da borda direita.
     */
    public void setRightColor(Color color){
        this.rightColor = color;
    }
    
    /**
     * Remove todas as cores definidas para a borda.
     * Utiliza-se no lugar a cor de fundo do componente.
     */
    public void removeAllColors(){
        this.topColor = null;
        this.bottomColor = null;
        this.leftColor = null;
        this.rightColor = null;
    }
    
    // </editor-fold>
}
